/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package analiseSintatica.Regras.Blocos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Comandos.RegraInstrucao;
import analiseSintatica.Regras.Funcao.RegraFuncao;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;
import java.util.LinkedList;

/**
 *
 * @author Dede do Bem
 */
public class RegraCorpoFuncao extends Regra {


    protected static Regra instancia;

    protected String estrutura = "'{' {<instrucao>} '}'";
    
    /**
     * Construtor privado necessario ao singleton
     */
    private RegraCorpoFuncao(){

    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraCorpoFuncao getInstance() {
        if (instancia == null) {
            instancia = new RegraCorpoFuncao();
        }
        return (RegraCorpoFuncao) instancia;

    }


    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
         NoArvore terminalCorpoFuncao = new NoArvore("<corpo_funcao>", false);


         try {
        	 terminalCorpoFuncao.adicionaFilho(reconheceLexema(listaTokens, "delimitador", "{", estrutura));
         } catch (ErroSintaticoException e) {
				e.printStackTrace();
		   }

         while (RegraInstrucao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getLexema())||
                 RegraInstrucao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getToken())){
             try {
            	 terminalCorpoFuncao.adicionaFilho(RegraInstrucao.getInstance().analisar(listaTokens));
             } catch (ErroSintaticoException e) {
            	 e.printStackTrace();
             }
         }

         try {
        	 terminalCorpoFuncao.adicionaFilho(reconheceLexema(listaTokens, "delimitador", "}", estrutura));
         } catch (ErroSintaticoException e) {
				e.printStackTrace();
		   }

System.out.println("Terminei Regra Corpo funcao");
        return terminalCorpoFuncao;
    }

    @Override
    protected void setPrimeiro() {
        this.primeiro.add("{");
    }

    @Override
    protected void setSeguinte() {
        this.seguinte.add("char");
        this.seguinte.add("int");
        this.seguinte.add("float");
        this.seguinte.add("boolean");
        this.seguinte.add("void");
        this.seguinte.add("identificador");
        this.seguinte.add("typedef");
        this.seguinte.add("const");
        this.seguinte.add("$"); //To com dúvida nesse aqui!!

//        this.seguinte = RegraDeclsFinal.getInstance().getPrimeiro();
//        this.seguinte.remove("e");
//        this.seguinte = getUniao(seguinte, RegraPrograma.getInstance().getSeguinte());
//        this.seguinte = getUniao(seguinte, RegraDeclsInicial.getInstance().getSeguinte());
//        this.seguinte = getUniao(seguinte, RegraFuncao.getInstance().getSeguinte());
    }

    


}
